#ifndef _GOVT_CMD_HPP_
#define _GOVT_CMD_HPP_
/*******************************************************************************
 ** Name: cmd.hpp                                                             **
 ** Description: WorldObject-derived container objects                        **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 ** The contents of this file are subject to the terms of the                 **
 ** Common Development and Distribution License, Version 1.0 only             **
 ** (the "License").  You may not use this file except in compliance          **
 ** with the License.                                                         **
 **                                                                           **
 ** You can find a copy of the license in the LICENSE file within             **
 ** this distribution or at $WIKI/display/GOVT/License-software.              **
 ** Software distributed under the License is distributed on an "AS IS"       **
 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.           **
 ** See the License for the specific language governing permissions           **
 ** and limitations under the License.                                        **
 **                                                                           **
 ** When distributing Covered Code, include this CDDL header in each          **
 ** file and include the License file at $GAME_DIR/LICENSE.                   **
 ** If applicable, add the following below this header, with the indicated    **
 ** fields enclosed by brackets "[]" replaced with your own identifying       **
 ** information: Portions Copyright [yyyy] [name of copyright owner]          **
 **                                                                           **
 **                                                                           **
 ** Copyright (c) 2009-2011  Barry Gian James <gian@gamingods.net>            **
 ** All rights reserved.                                                      **
 ******************************************************************************/
// Modified $Date: 2012-08-14 20:47:30 -0600 (Tue, 14 Aug 2012) $ by $Author: unknown $

// Portions Copyright 2012 Open Design Strategies, LLC
// All Rights Reserved.

#define _cmd_hpp_ID    "$Id: cmd.hpp 69068 2012-08-15 02:47:30Z unknown $"

#include <odb/core.hxx>
#include <boost/flyweight.hpp>
#include <map>
#include "common.hpp"

enum class CmdType { Command, Predicate };

enum class CmdPriority { Low, Normal, High };

enum class CmdReturn { OK, Error, Priv, Unknown, Undefined, MissingTarget, NotAllowed };

#define CMD_NONE	0x0000
#define CMD_AGENT	0x0001
#define CMD_BUILDER	0x0002
#define CMD_HANDLER	0x0004
#define CMD_CONTROL	0x0008
#define CMD_FACTION	0x0010
#define CMD_FACTION_OWNER 0x0020
#define CMD_SHOP	0x0040
#define CMD_SHOP_OWNER 0x0080
#define CMD_NO_COMBAT 0x0100

// Syntax: Embedded objects
#define CMD_SYNTAX_OBJECT_ITEM		"<object:item>"
#define CMD_SYNTAX_OBJ_JEWELRY		"<object:item:jewelry>"
#define CMD_SYNTAX_OBJ_COMMON		"<object:item:common>"
#define CMD_SYNTAX_OBJ_CONSUMABLE	"<object:item:consumable>"
#define CMD_SYNTAX_OBJ_TOXIC		"<object:item:toxic>"
#define CMD_SYNTAX_OBJ_DECORATION	"<object:item:decoration>"
#define CMD_SYNTAX_OBJ_RESOURCE		"<object:item:resource>"
#define CMD_SYNTAX_OBJ_SCRATCH		"<object:item:scratch>"
#define CMD_SYNTAX_OBJ_CONTAINER	"<object:item:container>"
#define CMD_SYNTAX_OBJ_WEAPON		"<object:item:weapon>"
#define CMD_SYNTAX_OBJ_DEVICE		"<object:item:device>"
#define CMD_SYNTAX_OBJ_CHAR			"<object:char>"
#define CMD_SYNTAX_OBJ_SELF			"<object:self>"

#define CMD_REF_OBJ_NAME			"$name"
#define CMD_REF_TARGET_NAME			"$target"
#define CMD_REF_SELF_HESHE			"$heshe"
#define CMD_REF_SELF_HISHERS		"$hishers"
#define CMD_REF_SELF_HIMHER			"$himher"
#define CMD_REF_TARGET_HESHE		"$heshe"
#define CMD_REF_TARGET_HISHERS		"$thishers"
#define CMD_REF_TARGET_HIMHER		"$thimher"

class WorldObject;
class Command;
typedef CmdReturn	(*cmdfunc)(std::string & args);



//! @class Command
//! @brief The command class
//! Must be Assignable, Equality Comparable, and Boost.Hash compatible to
//! work with boost::flyweight classes.
#pragma db object table("commands")
class Command
{
public:
	SMART_PTR_DECL(Command);

	Command();
	Command(const Command &);

//	Command & operator = (const Command &);	// Assignable
	bool operator == (const Command &);		// Equality comparable
	bool operator != (const Command &);		// Equality comparable

	// Getters
	const entity_t	ID()const  { return _idcommand; }
	const std::string &	Name() const { return _name; }
	const std::string &	Desc() const { return _desc; }
	const std::string &	Example() const { return _example; }
	const std::string & 	Help() const { return _help; }
	const std::string &	Syntax() const { return _syntax; }
	const CmdType		Type() const { return _type; }
	const CmdPriority 	Priority() const { return _priority; }
	const entity_t		Category() const { return _idcategory; }
	const ushort		Cost() const { return _cost; }
	const ulong			Flags() const { return _flags; }
	const bool 			Enabled() const { return _enabled; }
//	const std::vector<entity_t> & SubCmds() const { return _subcmds; }
	const std::string &	Source() const { return _source; }
	const ulong			Access() const { return _access; }

	// Setters


	// Take a command string and parse it, executing it if ok
	CmdReturn		Execute(std::string &);

protected:
	friend class odb::access;

	#pragma db id auto
	entity_t	_idcommand;
	std::string	_name;
	std::string	_desc;
	std::string	_example;
	std::string	_help;
	std::string	_syntax;
	CmdType		_type;
	CmdPriority	_priority;
	entity_t	_idcategory;
	ushort		_cost;
	ulong		_access;
	int			_flags;
	bool		_enabled;
	std::string	_source;
};


namespace cmd
{
// this fct is necessary to load from db, assign the cmdfunc to the command object
// and add them all into the command map container
int	init();
void process();
void add_to_queue(std::string &);

extern std::vector<std::string> articles;	// isn't this superfluous? ~gian

extern std::map<std::string,cmdfunc> commands;
extern std::queue<std::string> cmd_queue;

}

#endif /* _GOVT_CMD_HPP_ */
